package com.cmes.jdbc.customquery;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cmes.core.Pagination;
import com.cmes.jdbc.entity.Entity;
import com.cmes.jdbc.repository.GenericRepository;

import java.util.List;
import java.util.function.Consumer;

/**
 * 自定义查询
 *
 * @author Bruce.Gong
 * @since 1.0.0-SNAPSHOT
 */
public interface ICustomQueryService<E extends Entity> {

    /**
     * 分定义查询
     *
     * @param bo 通用分页查询对象
     * @return Pagination  分页对象
     */
    default Pagination<E> page(CustomQueryBO bo) {
        return page(bo, e -> {
        });
    }

    /**
     * 翻页查询
     *
     * @param bo          通用分页查询对象
     * @param postWrapper 组装通用查询条件 QueryWrapper 之后的自定义处理函数，可以自行对查询条件进行调整
     * @return Pagination  分页对象
     */
    default Pagination<E> page(CustomQueryBO bo, Consumer<QueryWrapper<E>> postWrapper) {
        Pagination<E> pagination = new Pagination<>(bo.getPage(), bo.getPageSize());
        QueryWrapper<E> queryWrapper = customQueryWrapper(bo);
        postWrapper.accept(queryWrapper);
        Page<E> page = new Page<>(pagination.getPageNum(), pagination.getPageSize());
        page = getGenericRepository().selectPage(page, queryWrapper);
        return pagination.of(page.getRecords(), page.getTotal());
    }

    default List<E> list(CustomQueryBO bo) {
        return list(bo, v -> {
        });
    }

    /**
     * 翻页查询
     *
     * @param bo          通用分页查询对象
     * @param postWrapper 组装通用查询条件 QueryWrapper 之后的自定义处理函数，可以自行对查询条件进行调整
     * @return Pagination  分页对象
     */
    default List<E> list(CustomQueryBO bo, Consumer<QueryWrapper<E>> postWrapper) {
        QueryWrapper<E> queryWrapper = customQueryWrapper(bo);
        postWrapper.accept(queryWrapper);
        return getGenericRepository().selectList(queryWrapper);
    }

    /**
     * 根据前端提供的参数，组装查询条件
     *
     * @param bo 查询对象
     * @return 查询条件
     */
    QueryWrapper<E> customQueryWrapper(CustomQueryBO bo);

    /**
     * 获取对象的 Repository
     *
     * @return Repository
     */
    GenericRepository<E> getGenericRepository();

    /**
     * 获取业务对象
     *
     * @return Class
     */
    Class<E> currentEntityClass();

}
